/** @file
 *  @brief Bluetooth Mesh Configuration Client Model APIs.
 */

/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef __BT_MESH_CFG_CLI_H
#define __BT_MESH_CFG_CLI_H

/**
 * @brief Bluetooth Mesh
 * @defgroup bt_mesh_cfg_cli Bluetooth Mesh Configuration Client Model
 * @ingroup bt_mesh
 * @{
 */
#ifdef __cplusplus
extern "C" {
#endif

/** Mesh Configuration Client Model Context */
struct bt_mesh_cfg_cli {
    struct bt_mesh_model *model;

    struct k_sem op_sync;
    bt_u32_t op_pending;
    void *op_param;
};

extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[];
extern struct bt_mesh_cfg_cli g_cfg_cli;

#define BT_MESH_MODEL_CFG_CLI(cli_data) BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_op, NULL, cli_data)

#define MESH_MODEL_CFG_CLI_NULL() BT_MESH_MODEL_CFG_CLI(&g_cfg_cli)

int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, u8_t *status, struct net_buf_simple *comp);

int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status);

int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status);

int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl);

int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl);

int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status);

int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status);

int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status);

int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status);

int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status, u8_t *transmit);

int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay, u8_t new_transmit, u8_t *status, u8_t *transmit);

int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, const u8_t net_key[16], u8_t *status);

int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16],
                            u8_t *status);

int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u8_t *status);

int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid,
                                 u8_t *status);

int bt_mesh_cfg_mod_app_unbind(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id,
                               u8_t *status);

int bt_mesh_cfg_mod_app_unbind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id,
                                   u16_t cid, u8_t *status);

int bt_mesh_cfg_net_key_update(u16_t net_idx, u16_t addr, u16_t key_net_idx, const u8_t net_key[16], u8_t *status);

int bt_mesh_cfg_app_key_update(u16_t net_idx, u16_t addr, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16],
                               u8_t *status);

/** @def BT_MESH_PUB_PERIOD_100MS
 *
 *  @brief Helper macro to encode model publication period in units of 100ms
 *
 *  @param steps Number of 100ms steps.
 *
 *  @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period
 */
#define BT_MESH_PUB_PERIOD_100MS(steps) ((steps) & BIT_MASK(6))

/** @def BT_MESH_PUB_PERIOD_SEC
 *
 *  @brief Helper macro to encode model publication period in units of 1 second
 *
 *  @param steps Number of 1 second steps.
 *
 *  @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period
 */
#define BT_MESH_PUB_PERIOD_SEC(steps) (((steps) & BIT_MASK(6)) | (1 << 6))

/** @def BT_MESH_PUB_PERIOD_10SEC
 *
 *  @brief Helper macro to encode model publication period in units of 10
 *  seconds
 *
 *  @param steps Number of 10 second steps.
 *
 *  @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period
 */
#define BT_MESH_PUB_PERIOD_10SEC(steps) (((steps) & BIT_MASK(6)) | (2 << 6))

/** @def BT_MESH_PUB_PERIOD_10MIN
 *
 *  @brief Helper macro to encode model publication period in units of 10
 *  minutes
 *
 *  @param steps Number of 10 minute steps.
 *
 *  @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period
 */
#define BT_MESH_PUB_PERIOD_10MIN(steps) (((steps) & BIT_MASK(6)) | (3 << 6))

struct bt_mesh_cfg_mod_pub {
    u16_t addr;
    u16_t app_idx;
    bool cred_flag;
    u8_t ttl;
    u8_t period;
    u8_t transmit;
};

int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
                            u8_t *status);

int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
                                struct bt_mesh_cfg_mod_pub *pub, u8_t *status);

int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub,
                            u8_t *status);

int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t mod_id, u16_t cid,
                                struct bt_mesh_cfg_mod_pub *pub, u8_t *status);

int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u8_t *status);

int bt_mesh_cfg_mod_sub_get(u16_t net_idx, u16_t addr, u16_t mod_id, uint16_t *sub, u8_t *status);

int bt_mesh_cfg_mod_sub_get_vnd(u16_t net_idx, u16_t addr, u16_t mod_id, u16_t cid, uint16_t *sub, u8_t *status);

int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid,
                                u8_t *status);

int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u8_t *status);

int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid,
                                u8_t *status);

int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id,
                                  u8_t *status);

int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, u16_t sub_addr, u16_t mod_id,
                                      u16_t cid, u8_t *status);

int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                               u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                                   u16_t cid, u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                               u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                                   u16_t cid, u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                                     u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, const u8_t label[16], u16_t mod_id,
                                         u16_t cid, u16_t *virt_addr, u8_t *status);

int bt_mesh_cfg_node_reset(u16_t net_idx, u16_t addr);

int bt_mesh_cfg_krp_set(u16_t net_idx, u16_t addr, u16_t key_net_idx, u8_t *phase, u8_t *status);
int bt_mesh_cfg_krp_get(u16_t net_idx, u16_t addr, u16_t key_net_idx, u8_t *phase, u8_t *status);

struct bt_mesh_cfg_hb_sub {
    u16_t src;
    u16_t dst;
    u8_t period;
    u8_t count;
    u8_t min;
    u8_t max;
};

int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status);

int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_sub *sub, u8_t *status);

struct bt_mesh_cfg_hb_pub {
    u16_t dst;
    u8_t count;
    u8_t period;
    u8_t ttl;
    u16_t feat;
    u16_t net_idx;
};

int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr, const struct bt_mesh_cfg_hb_pub *pub, u8_t *status);

int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr, struct bt_mesh_cfg_hb_pub *pub, u8_t *status);

/*[Genie begin] add by wenbing.cwb at 2021-01-21*/
#ifdef CONFIG_BT_MESH_CTRL_RELAY
int bt_mesh_cfg_ctrl_relay_get(u16_t net_idx, u16_t addr, struct ctrl_relay_param *cr, u8_t *status);

int bt_mesh_cfg_ctrl_relay_set(u16_t net_idx, u16_t addr, const struct ctrl_relay_param *cr, u8_t *status);
#endif
/*[Genie end] add by wenbing.cwb at 2021-01-21*/

bt_s32_t bt_mesh_cfg_cli_timeout_get(void);
void bt_mesh_cfg_cli_timeout_set(bt_s32_t timeout);

#ifdef __cplusplus
}
#endif
/**
 * @}
 */

#endif /* __BT_MESH_CFG_CLI_H */
